package SimpleLACore

import chisel3._
import chisel3.util._
import Consts._

object ALU {
  def alu(a: UInt, b: UInt, func: UInt): UInt = {
    val sa = a.asSInt()
    val sb = b.asSInt()
    Mux1H(Seq(
      (func === alu_ADD  ) -> (a + b).asUInt()(31, 0),
      (func === alu_SUB  ) -> (a - b).asUInt()(31, 0),
      (func === alu_SLL  ) -> (a << b(4, 0)).asUInt()(31, 0),
      (func === alu_SRL  ) -> (a >> b(4, 0)).asUInt()(31, 0),
      (func === alu_SRA  ) -> (sa >> b(4, 0)).asUInt()(31, 0),
      (func === alu_AND  ) -> (a & b).asUInt()(31, 0),
      (func === alu_OR   ) -> (a | b).asUInt()(31, 0),
      (func === alu_NOR  ) -> (~(a | b)).asUInt()(31, 0),
      (func === alu_XOR  ) -> (a ^ b).asUInt()(31, 0),
      (func === alu_SLT  ) -> (sa < sb).asUInt(),
      (func === alu_SLTU ) -> (a < b).asUInt(),
      (func === alu_COPY ) -> b.asUInt()(31, 0),
      (func === alu_MUL  ) -> (sa * sb).asUInt()(31, 0),
      (func === alu_MULH ) -> (sa * sb).asUInt()(63, 32),
      (func === alu_MULHU) -> (a * b).asUInt()(63, 32),
      (func === alu_MOD  ) -> (sa % sb).asUInt()(31, 0),
      (func === alu_DIV  ) -> (sa / sb).asUInt()(31, 0),
      (func === alu_MODU ) -> (a % b).asUInt()(31, 0),
      (func === alu_DIVU ) -> (a / b).asUInt()(31, 0),
    ))
    //    VecInit(
    //      (a + b).asUInt(),
    //      (a - b).asUInt(),
    //      (a << b(4, 0)).asUInt(),
    //      (a >> b(4, 0)).asUInt(),
    //      (sa >> b(4, 0)).asUInt(),
    //      (a & b).asUInt(),
    //      (a | b).asUInt(),
    //      (~(a | b)).asUInt(),
    //      (a ^ b).asUInt(),
    //      (sa < sb).asUInt(),
    //      (a < b).asUInt(),
    //      b.asUInt(),
    //      (sa * sb) (31, 0).asUInt(),
    //      (sa * sb) (63, 32).asUInt(),
    //      (a * b) (63, 32).asUInt(),
    //      (sa % sb).asUInt(),
    //      (sa / sb).asUInt(),
    //      (a % b).asUInt(),
    //      (a / b).asUInt(),
    //    )(func)
  }
}
